package com.tuton.javanet.chapter04;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class UnblockEchoClient {
	
	SocketChannel socketChannel = null;
	ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
	ByteBuffer revceiveBuffer = ByteBuffer.allocate(1024);
	Charset charSet = Charset.forName("GBK");
	Selector selector;
	
	public UnblockEchoClient() throws IOException {
		socketChannel = SocketChannel.open();
		InetAddress ia = InetAddress.getLocalHost();
		InetSocketAddress isa = new InetSocketAddress(ia,8000);
		socketChannel.connect(isa);
		System.out.println("Connectet to server...");
		selector = Selector.open();
		
	}
	
	public void receiveFromUser() {
		BufferedReader localBuffered = new BufferedReader(new InputStreamReader(System.in));
		String msg = null;
		try{	
			while((msg = localBuffered.readLine())!= null) {
				synchronized(sendBuffer){
					sendBuffer.put(encode(msg + "\r\n"));
				}
				
				if("bye".equalsIgnoreCase(msg)){
					break;
				}
			}
		} catch(IOException ex) {
			ex.printStackTrace();
		}
	}
	
	
	private void talk() throws IOException {
		try {
			socketChannel.register(selector, SelectionKey.OP_READ |
					SelectionKey.OP_WRITE);
		} catch (ClosedChannelException e) {
			e.printStackTrace();
		}
		while(selector.select() > 0) {
			Set<SelectionKey> readyKeys = selector.selectedKeys();
			Iterator keyIter = readyKeys.iterator();
			while(keyIter.hasNext()){
				SelectionKey key = (SelectionKey) keyIter.next();
				keyIter.remove();
				
				if(key.isReadable()) {
				    reveive(key);	
				}
				else if(key.isWritable()) {
					send(key);
				}
				try{
					if(key != null) {
						key.cancel();
						key.channel().close();
					}
				} catch(Exception e){
					e.printStackTrace();
				}
			}
		}
	}
	
	public void send(SelectionKey key){
		SocketChannel socketChannel = (SocketChannel) key.channel();
		synchronized(sendBuffer){
			
		}
	}
	
	public void reveive(SelectionKey key){
		
	}
	
	private ByteBuffer encode(String str) {
		return charSet.encode(str);
	}

	private String decode(ByteBuffer byteBuffer){
		CharBuffer charBuffer = charSet.decode(byteBuffer);
		return charBuffer.toString();
	}
	
	public static void main(String[] args) throws IOException {
		final UnblockEchoClient client = new UnblockEchoClient();
		Thread clentThread = new Thread(){
			public void run(){
				client.receiveFromUser();
			}

		};
		                           
		client.talk();
	}

}
